package com.qin.entity.subcomponents;

import com.qin.entity.Component;
import com.qin.entity.ExecuteBean;
import com.qin.entity.ExecuteLog;
import com.qin.service.ComponentService;
import com.qin.service.ExecuteService;
import com.qin.service.impl.ComponentServiceImpl;
import com.qin.service.impl.ExecuteServiceImpl;

import java.util.HashMap;
import java.util.Map;

/*
 * 【子组件】变量轮询
 */
public class PollSubComponent {

    //所属组件ID
    private String component_id;
    //临时变量名
    private String poll_paraname;
    //提取列名
    private String poll_column_name;
    //目标值
    private String poll_target_value;
    //轮询间隔
    private int poll_interval;
    //轮询时长
    private int poll_duaration;

    private ExecuteService executeService = new ExecuteServiceImpl();

    public PollSubComponent(String component_id, String poll_paraname, String poll_column_name, String poll_target_value, int poll_interval, int poll_duaration) {
        this.component_id = component_id;
        this.poll_paraname = poll_paraname;
        this.poll_column_name = poll_column_name;
        this.poll_target_value = poll_target_value;
        this.poll_interval = poll_interval;
        this.poll_duaration = poll_duaration;
    }

    public void execute(ExecuteBean executeBean){

        //设置ExecuteLog对象的各属性
        ExecuteLog executeLog = new ExecuteLog(executeBean.getExecute_id(), executeBean.getFunction_id(),
                executeBean.getTestcase_id(), executeBean.getComponent_id(), executeBean.getSubcomponent_id(), "");

        //获取父组件查询结果的第一条
        Map<String, String> resultMap = executeBean.getDbQueryResultMap().get(component_id).get(0);
        //获取对列名下对应的查询结果
        String poll_real_value = resultMap.get(poll_column_name.toUpperCase());

        Map<String, String> retMap = new HashMap();
        retMap.put(poll_paraname, poll_real_value);
        //把map的值添加到executeBean中
        executeBean.getParaMap().putAll(retMap);

        //打印当前实际值和轮询目标值
        //插入日志
        executeService.insertExecuteLog(executeLog, ">>>>>变量轮询：提取列名" + poll_column_name + "的值到变量" + poll_paraname);
        executeService.insertExecuteLog(executeLog, ">>>>>变量轮询：变量" + poll_paraname + "，当前实际值=" + poll_real_value + "，轮询目标值=" + poll_target_value);

        //定义计秒变量timeCount
        int timeCount = 0;

        //当前实际值<>轮询目标值，则开始轮询
        if(!poll_real_value.equals(poll_target_value)){

            //插入日志
            executeService.insertExecuteLog(executeLog, ">>>>>变量轮询：轮询开始");

            //定义与父组件一样Component对象：tempComponent
            ComponentService componentService = new ComponentServiceImpl();
            Component c = new Component();
            c.setComponent_id(component_id);
            Component tempComponent = componentService.queryComponentByComponentId(c);
            //设置tempComponent不执行子组件，不打印日志
            tempComponent.setExec_subCom_flag(false);
            tempComponent.setPrint_log_flag(false);

            //轮询直到：
            // 1、timeCount不下于轮询时长poll_duaration
            // 2、poll_real_value == poll_target_value
            while(timeCount < poll_duaration && !poll_real_value.equals(poll_target_value)){
                try {
                    synchronized (Thread.currentThread()){
                        //线程等待poll_interval秒
                        if(timeCount + poll_interval < poll_duaration){
                            Thread.currentThread().wait(poll_interval*1000);
                            timeCount += poll_interval;
                        }
                        else{
                            int last_interval = poll_duaration - timeCount;
                            Thread.currentThread().wait(last_interval*1000);
                            timeCount += last_interval;
                        }

                        //执行tempComponent
                        tempComponent.execute(executeBean);
                        //获取tempComponent查询结果的第一条
                        Map<String, String> tempMap = executeBean.getDbQueryResultMap().get(component_id).get(0);
                        //获取对列名下对应的查询结果
                        poll_real_value = tempMap.get(poll_column_name.toUpperCase());

                        //插入日志
                        executeService.insertExecuteLog(executeLog, ">>>>>变量轮询：【轮询间隔"+poll_interval+"s，已轮询"+timeCount+"s，轮询时长"+poll_duaration+"s】"
                                                                                + "当前实际值："+poll_real_value+"，轮询目标值："+poll_target_value);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        //轮询通过，即在轮询时长poll_duaration时间内，实际值==轮询目标值
        if(timeCount <= poll_duaration && poll_real_value.equals(poll_target_value)){
            //插入日志
            executeService.insertExecuteLog(executeLog, ">>>>>变量轮询：轮询结束，轮询通过");
        }
        //轮询不通过，即在轮询时长poll_duaration时间内，实际值<>轮询目标值
        else{
            //插入日志
            executeService.insertExecuteLog(executeLog, ">>>>>变量轮询：轮询结束，轮询不通过");
            throw new NullPointerException();
        }

    }
}
